package com.hry.myapp.controllers;

import java.io.Console;
import java.net.http.HttpHeaders;

import java.net.http.HttpResponse;
import java.util.Calendar;
import java.util.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.swing.text.html.HTMLDocument.Iterator;

import org.apache.catalina.realm.AuthenticatedUserRealm;
import org.apache.http.HttpStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import com.hry.myapp.beans.WXAllUserAuthTypes;
import com.hry.myapp.beans.WXAppInfo;
import com.hry.myapp.beans.WXServiceInfo;
import com.hry.myapp.beans.WXUser;
import com.hry.myapp.beans.WXUserAccount;
import com.hry.myapp.beans.WXUserAddress;
import com.hry.myapp.beans.WXUserLogin;
import com.hry.myapp.beans.WXUserTypeAuth;
import com.hry.myapp.mapper.IUserAccountMapper;
import com.hry.myapp.mapper.IUserAddressMapper;
import com.hry.myapp.mapper.IUserMapper;
import com.hry.myapp.mapper.IUserTypeAuthMapper;
import com.hry.myapp.servlet.impl.UserAccountImpl;
import com.hry.myapp.servlet.impl.UserAddressImpl;
import com.hry.myapp.servlet.impl.UserLoginImpl;
import com.hry.myapp.servlet.impl.UserServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.BeanUtils;
import com.hry.myapp.utils.CommonUtils;
import com.hry.myapp.utils.HttpUtils;
import com.hry.myapp.utils.JsonUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

@Controller
public class WXUserController {
	
	@Autowired
	UserServiceImpl userService ;
	
	@Autowired
	UserAccountImpl userAccount ;
	
	@Autowired
	UserLoginImpl userLogin ;
	
	@Autowired
	WXAppInfo wxAppInfo ;
	
    @Autowired
    RestTemplate restTemplate;
    
	@Autowired
	IUserTypeAuthMapper userTypeAuth ;
	
	@Autowired
	UserAddressImpl userAddress ;
	

	

	
//  添加新用户
    @ResponseBody
	@PostMapping("/wxuser")
	public Map toAddWXUser(HttpServletRequest request) throws JsonMappingException, JsonProcessingException, ParseException {
    	
        Map body = (Map<String,Object>)request.getAttribute("body");
        
        String openid = (String)request.getAttribute("openid");
        String session_key = (String)request.getAttribute("session_key");
        Boolean isNewUser = (Boolean)request.getAttribute("isNew");
        
		Map resultMap = new HashMap<>() ;
		

        if(!isNewUser) {
        	
            QueryWrapper<WXUser> userQueryWrapper = new QueryWrapper<>() ;
            
            userQueryWrapper.eq("user_code", openid) ;
       
            
            WXUser user = userService.getOne(userQueryWrapper) ;
            
            Map userMap = CommonUtils.ObjectToMap(user) ;
        	
        	QueryWrapper<WXUserLogin> userLoginQueryWrapper = new QueryWrapper<>() ;
        	
        	userLoginQueryWrapper.eq("user_id", userMap.get("id")) ;
        	
        	Map cookieMap = userLogin.getMap(userLoginQueryWrapper) ;
        	
        	
        	
//        	获取用户认证状态
    		WXAllUserAuthTypes wuta = new WXAllUserAuthTypes() ;
    		String[] allTypes = wuta.getAllTypes() ;
    		
    		
    		int user_type = Integer.parseInt(userMap.get("user_type").toString()) ;
    		String ut = allTypes[user_type] ;
    		
    		Map typeMap = new HashMap<>() ;
    		typeMap.put("ut", ut) ; // 根据认证类型决定查询哪个表
    		typeMap.put("user_id", userMap.get("id")) ; //根据用户id查询
    		
    		WXUserTypeAuth wxUserTypeAuth = userTypeAuth.getUserByUid(typeMap) ;
    		userMap.put("progress", wxUserTypeAuth.getProgress()) ;
    		
//    		cookie更新
	   		 Calendar calendar = Calendar.getInstance();
	   		 calendar.setTime(new Date());
	   	     calendar.add(Calendar.DATE, wxAppInfo.getCookieExpire());
	
	   		
	   		UpdateWrapper<WXUserLogin> updateWrapper = new UpdateWrapper<>();
	   		updateWrapper.eq("user_id",userMap.get("id")).set("expired_at", calendar.getTime()) ;
	
	
	   		userLogin.update(null, updateWrapper);
    		

    		resultMap.put("userInfo", userMap) ;
    		resultMap.put("cookie", cookieMap) ;
    		

        	
        }else {
        	
        	
        	Map userInfo = (Map<String,Object>)body.get("userInfo") ;
        	int user_type = Integer.parseInt((String)body.get("user_type")) ;
        	
        	
    		Map userAccountMap = new HashMap<>();
    		userAccountMap.putAll(userInfo);
    		
    		Map userMap = new HashMap<>();
    		userMap.putAll(userInfo);
    		userMap.put("user_type", user_type) ;
    		userMap.put("user_code", openid) ;
    		
    		WXUser user = CommonUtils.mapToObject(userMap, WXUser.class) ;
        	
    		userService.saveOrUpdate(user);
    		
//    		t_user_account表插入
    		int uid = user.getId() ;
    		userAccountMap.put("user_id", uid) ;
    		userAccountMap.put("session_key", session_key) ;
    		userAccountMap.put("openid", openid) ;
//
    		WXUserAccount uc = CommonUtils.mapToObject(userAccountMap, WXUserAccount.class) ;
    		
    		userAccount.saveOrUpdate(uc) ;
    		
//    		t_user_login表插入
    		Map userLoginMap = new HashMap<>();
    		userLoginMap.put("user_id", uid) ;
//    		
            Date now = new Date() ;
            long ts = now.getTime();
            ts += 2 * 24 * 60 * 60 * 1000 ;
//             
            userLoginMap.put("expiredAt", ts) ;
            userLoginMap.put("user_type", user_type) ;
            
            WXUserLogin ul = CommonUtils.mapToObject(userLoginMap, WXUserLogin.class) ;
//
    		userLogin.saveOrUpdate(ul) ;
    		
//    		回设id，用于返回，不知道为啥不会自动设置上就手动设置了    		
    		userMap.put("id", uid) ;
    		ul.setId(ul.getId());
    		
    		
//    		t_address表插入
//    		Map userAddressMap = new HashMap<>() ;
//    		userAddressMap.put("user_id", uid) ;
//            WXUserAddress ud = CommonUtils.mapToObject(userAddressMap, WXUserAddress.class) ;
//    		userAddress.saveOrUpdate(ud) ;


    		
//    		红人认证类型插入
    		WXAllUserAuthTypes wuta = new WXAllUserAuthTypes() ;
    		String[] allTypes = wuta.getAllTypes() ;
    		
//    		根据类型决定查询哪个表
    		String ut = allTypes[user_type] ;
    		
    		WXUserTypeAuth uta = new WXUserTypeAuth() ;
    		uta.setUser_id(uid) ;
    		uta.setProgress(0) ;
    		uta.setCreatedAt(new Date());
    		uta.setUpdatedAt(new Date());

    		
    		Map utaMap = new HashMap<>() ;
    		utaMap.put("ut", ut) ;
    		utaMap.put("uta", uta) ;
    		
    		
    		userTypeAuth.insertInitUser(utaMap);
    		
    		resultMap.put("userInfo", userMap) ;
    		resultMap.put("cookie", ul) ;
    		
    		
        }
        
		return resultMap ;
        

		
	}
	
//	获取用户信息
    @ResponseBody
	@GetMapping("/wxuser")
	public Map getUser(@RequestParam Map<String, Object> map) throws JsonMappingException, JsonProcessingException {
    	
    	
		String code = (String)map.get("code");
		
		
		StringBuilder urlPath = new StringBuilder(wxAppInfo.getOpenUrl());
		
//		路径拼接
        urlPath.append(String.format("?appid=%s", wxAppInfo.getAppid()));
        urlPath.append(String.format("&secret=%s", wxAppInfo.getSecret()));
        urlPath.append(String.format("&js_code=%s", code));
        urlPath.append(String.format("&grant_type=%s", wxAppInfo.getAuthCode())); 
        
        
        ResponseEntity<String> responseObject = restTemplate.getForEntity(urlPath.toString(), String.class);        
        
        String appInfo = responseObject.getBody();
  
        
        JsonUtils jUtils = new JsonUtils() ;
         
        Map<String,Object> resultMap = jUtils.jsonToMap(appInfo);
        
        String openid = (String) resultMap.get("openid");
        		    	
        QueryWrapper<WXUser> userQueryWrapper = new QueryWrapper<>() ;
        
        userQueryWrapper.eq("user_code", openid) ;
   
        
        WXUser user = userService.getOne(userQueryWrapper) ;
        
        Map userMap = CommonUtils.ObjectToMap(user) ;
    	
    	QueryWrapper<WXUserLogin> userLoginQueryWrapper = new QueryWrapper<>() ;
    	
    	userLoginQueryWrapper.eq("user_id", userMap.get("id")) ;
    	
    	Map cookieMap = userLogin.getMap(userLoginQueryWrapper) ;
    	
//    	获取用户认证状态
		WXAllUserAuthTypes wuta = new WXAllUserAuthTypes() ;
		String[] allTypes = wuta.getAllTypes() ;
		
		

    	int user_type = Integer.parseInt(userMap.get("user_type").toString()) ;

		String ut = allTypes[user_type] ;
		
		Map typeMap = new HashMap<>() ;
		typeMap.put("ut", ut) ; // 根据认证类型决定查询哪个表
		typeMap.put("user_id", userMap.get("id")) ; //根据用户id查询
		
		WXUserTypeAuth wxUserTypeAuth = userTypeAuth.getUserByUid(typeMap) ;
		userMap.put("progress", wxUserTypeAuth.getProgress()) ;
		
//		cookie更新
   		 Calendar calendar = Calendar.getInstance();
   		 calendar.setTime(new Date());
   	     calendar.add(Calendar.DATE, wxAppInfo.getCookieExpire());

   		
   		UpdateWrapper<WXUserLogin> updateWrapper = new UpdateWrapper<>();
   		updateWrapper.eq("user_id",userMap.get("id")).set("expired_at", calendar.getTime()) ;


   		userLogin.update(null, updateWrapper);
		
		
		Map rMap = new HashMap<>() ;
		rMap.put("userInfo", userMap) ;
		rMap.put("cookie", cookieMap) ;
		
		return rMap ;
//		
	}
    
    
//  退出登陆
	@ResponseBody
	@DeleteMapping("/wxuser")
	public String logout(@RequestParam("uid") int uid) {
		
		
		 Calendar calendar = Calendar.getInstance();
		 calendar.setTime(new Date());
	     calendar.add(Calendar.DATE, -1 * wxAppInfo.getCookieExpire());
		
		

		
//		设置过期时间为三天前，保证是过期的，所以可以在不用删除数据相应字段的情况下实现cookie删除的效果
	
		
		UpdateWrapper<WXUserLogin> updateWrapper = new UpdateWrapper<>();
		updateWrapper.eq("user_id",uid).set("expired_at", calendar.getTime()) ;


		userLogin.update(null, updateWrapper);
    	
    	return "ok" ;
		
	}
	
//	更新用户信息
	@ResponseBody
	@PutMapping("/wxuser")
	public WXUser updateUser(@RequestParam Map newuser) {
		
		WXUser user =  CommonUtils.mapToObject(newuser, WXUser.class) ;
		
//		UpdateWrapper<WXUser> updateWrapper = new UpdateWrapper<>();
//		updateWrapper.eq("id", user.getId()) ;
		
		userService.saveOrUpdate(user) ;
		System.out.println(user.getUser_code());
		return user ;
	}
	
//	判断用户状态是否有效
    @ResponseBody
	@GetMapping("/avauser")
	public Map isAva(@RequestParam("id") int id) {
		
    	System.out.println(id);

		WXUserLogin wLogin = userLogin.getById(id) ;

				
		Date nowDate = new Date() ;
		Long n = nowDate.getTime() ;
		Long p = ((Date)wLogin.getExpiredAt()).getTime() ;
		
		Map rMap = new HashMap<>() ;
		
		rMap.put("isAva", n>=p? 0:1) ;
		rMap.put("uid", wLogin.getUser_id()) ;
		return rMap ;
		
	}
	
//	
	
	
	
//	判断是否为新用户并进行转发请求
	@PostMapping("/newuser")
	public String isNewUser(@RequestBody Map<String, Object> map, HttpServletRequest request) throws JsonMappingException, JsonProcessingException {
		
		String code = (String)map.get("code");
		
		StringBuilder urlPath = new StringBuilder(wxAppInfo.getOpenUrl());
		
//		路径拼接
        urlPath.append(String.format("?appid=%s", wxAppInfo.getAppid()));
        urlPath.append(String.format("&secret=%s", wxAppInfo.getSecret()));
        urlPath.append(String.format("&js_code=%s", code));
        urlPath.append(String.format("&grant_type=%s", wxAppInfo.getAuthCode())); 
        
        
        ResponseEntity<String> responseObject = restTemplate.getForEntity(urlPath.toString(), String.class);        
        
        String appInfo = responseObject.getBody();
  
        
        JsonUtils jUtils = new JsonUtils() ;
         
        Map<String,Object> resultMap = jUtils.jsonToMap(appInfo);
        
        String openid = (String) resultMap.get("openid");
        String session_key= (String)resultMap.get("session_key") ;
        
        QueryWrapper<WXUser> queryWrapper = new QueryWrapper<>() ;
        
        queryWrapper.eq("user_code", openid) ;
        
        int userCount = userService.count(queryWrapper) ;
        
        if(userCount > 0) {
        	System.out.println("不是新用户");
        	request.setAttribute("isNew", false);
        	
        }else {
        	
        	request.setAttribute("isNew", true);
        	
        }
        
        request.setAttribute("body", map);
        request.setAttribute("openid", openid);
        request.setAttribute("session_key", session_key);
                
		return "forward:/wxuser";
	
	}
	
//	查询用户所有收货地址
	@ResponseBody
	@GetMapping("/wxaddress")
	public List<WXUserAddress> getAdress(@RequestParam("user_id") int uid){
		
		System.out.println("用户编号："+uid);
		QueryWrapper<WXUserAddress> queryWrapper = new QueryWrapper<>() ;
		queryWrapper.eq("user_id", uid) ;
		
		List<WXUserAddress> ld = userAddress.list(queryWrapper) ;
		
		return ld ;
		
	}
	
//	添加或者更新收货地址信息
	@ResponseBody
	@PostMapping("/wxaddress")
	public Map saveOrUpdateAddress(@RequestBody WXUserAddress addr) {
		
		Map resultMap = new HashMap<>() ;
	
		userAddress.saveOrUpdate(addr) ;
		
		resultMap.put("id",addr.getId() ) ;
		
		return resultMap ;
	}
	
//	删除地址
	@ResponseBody
	@DeleteMapping("/wxaddress")
	public boolean deleteAddress(@RequestParam("id") int id) {
		
		
		boolean su =  userAddress.removeById(id) ;
		
		return su ;
		
	}

	
	@ResponseBody
	@PostMapping("/t1")
	public String t1(@RequestBody Map<String, Object> map, HttpServletRequest request) {
		
		WXUserTypeAuth uta = new WXUserTypeAuth() ;
		uta.setUser_id(1001) ;
		uta.setProgress(0) ;
		
		Map mm = new HashMap<>() ;
		mm.put("ut", "t_hong_ren") ;
		mm.put("uta", uta) ;

		
		userTypeAuth.insertInitUser(mm);
		
		return "forward:/t2" ;
		
	}
	
	
	@ResponseBody
	@DeleteMapping("/t2")
	public String t2(HttpServletRequest request) {
		

		return "111" ;
	}
	


}
